home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
src
/
haeberli
/
libgutil
/
getfile.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
8KB
|
332 lines
/*
* Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
* All Rights Reserved.
*
* This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
* the contents of this file may not be disclosed to third parties, copied or
* duplicated in any form, in whole or in part, without the prior written
* permission of Silicon Graphics, Inc.
*
* RESTRICTED RIGHTS LEGEND:
* Use, duplication or disclosure by the Government is subject to restrictions
* as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
* and Computer Software clause at DFARS 252.227-7013, and/or in similar or
* successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
* rights reserved under the Copyright Laws of the United States.
*/
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <sys/fcntl.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <errno.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <netdb.h>
#include <device.h>
#include <gl.h>
#include <ctype.h>
#ifdef __cplusplus
#include <osfcn.h>
#endif /* __cplusplus */
#include <stdio.h>
#include <strings.h>
#ifdef __cplusplus
#include <libc.h>
#include <malloc.h>
#endif /* __cplusplus */
#define GIZMO_DIRECTORY "/usr/lib/showcase/"
static browsefd, childpid, browsegizmodead;
static long oldshowcase = -1;
static void errormessage(char *s)
{
fprintf(stderr, "%s\n", s);
}
/* for browsegizmo, call this as:
*
* doexec("browsegizmo", xctr, yctr, file, dir, 0);
*
*/
/*VARARGS*/
static int doexec(char *s, char *xctr, char *yctr,
char *file, char *dir)
{
struct sockaddr_in saddr;
int sock1, len, child, fd;
char *gargv[20];
char charportnum[200], gizmopath[100];
struct stat statbuf;
/* Create a socket for accepting the connection. */
if (stat(s,&statbuf) < 0)
sprintf(gizmopath, "%s%s", GIZMO_DIRECTORY, s);
else
sprintf(gizmopath, "./%s", s);
sock1 = socket(AF_INET, SOCK_STREAM, 0);
if(sock1 < 0) {
/*perror("error opening socket");*/
errormessage("Error opening gizmo.");
return 0;
}
/* Create name for parent socket on local machine. */
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = INADDR_ANY;
saddr.sin_port = 0;
if(bind(sock1, &saddr, sizeof(saddr))) {
/*perror("binding parent socket");*/
close(sock1);
errormessage("Error opening gizmo.");
return 0;
}
/* Find out port number assigned to parent socket. */
len = sizeof(saddr);
if(getsockname(sock1, &saddr, &len)) {
/*perror("getting parent socket name");*/
close(sock1);
errormessage("Error opening gizmo.");
return 0;
}
listen(sock1, 1 /* max size of queue of waiting connectors */);
child = fork();
if(child) {
retry:
fd = accept(sock1, 0, 0);
if(fd == -1) {
if (errno == EINTR)
goto retry;
sprintf(charportnum, "Failed to open gizmo.\nError %d", errno);
errormessage(charportnum);
kill(child,SIGKILL);
return 0;
}
browsefd = fd;
childpid = child;
close(sock1);
return 1;
} else {
/*sginap(2);*/
close(sock1);
sprintf(charportnum, "%d", ntohs(saddr.sin_port));
gargv[0] = gizmopath;
gargv[1] = charportnum;
gargv[2] = "4";
gargv[3] = xctr;
gargv[4] = yctr;
gargv[5] = oldshowcase ? "1" : file;
gargv[6] = oldshowcase ? file : dir;
gargv[7] = oldshowcase ? dir : 0;
gargv[8] = 0;
execvp(gizmopath, gargv);
perror("exec failed");
exit(1);
}
}
static int readbuf(int fd, char *p, int totbytes)
{
int nbytes, n;
nbytes = 0;
while (nbytes < totbytes) {
if ( (n=read(fd,p+nbytes,totbytes-nbytes)) < 0) {
if (errno == EINTR) continue;
/*perror("Showcase read failure");*/
return -1;
}
nbytes += n;
}
return nbytes;
}
static void readfromgizmo(char *buf, int nbytes)
{
if(readbuf(browsefd,buf,nbytes)<0){
errormessage("Can't read from gizmo");
kill(childpid,SIGKILL);
}
}
static void senddevtogizmo(long data)
{
write(browsefd,&data,sizeof(data));
}
static void sendgizmo(long data)
{
write(browsefd,&data,sizeof(data));
}
#define ABORT 20002
#define DIRNAMEDEV 20094
#define FILENAMEDEV 20082
#define NUKEFILENAMEDEV 20083
#define POKEGIZMO 20086
#define GIZMOINITEND 20136
#define DEADGIZMO 29999
static int halfbakedqread(int *val)
{
long n;
fd_set fdset;
int buf[2];
struct timeval timeout, *tp = &timeout;
while(1) {
tryagain:
if (browsegizmodead) {
*val = 0; return DEADGIZMO;
}
FD_ZERO(&fdset);
FD_SET(browsefd, &fdset);
tp = 0;
if ((n = select(FD_SETSIZE, &fdset, 0, 0, tp)) < 0) {
if (errno == EINTR) {
goto tryagain;
}
/*perror("select");*/
errormessage("Select error");
*val = 0;
return ABORT;
}
if(FD_ISSET(browsefd, &fdset)) {
if((n = readbuf(browsefd, (char *)buf, sizeof(buf))) < 0) {
/*perror("Showcase reading stream message");*/
errormessage("Gizmo read error");
kill(childpid,SIGKILL);
}
if (n == 0)
continue;
*val = buf[1];
return buf[0];
}
}
}
void getfilename(char *title, char *str, char *dir, long cx, long cy)
{
char *s;
int dev, val;
char xctr[10], yctr[10];
char *tmpdir, *tmpfilename;
struct stat statbuf;
mode_t omask;
if (oldshowcase == -1) {
if (stat("/usr/lib/showcase/audiogizmo", &statbuf) < 0)
oldshowcase = 1;
else
oldshowcase = 0;
}
*str = 0;
if (cx < 200) cx = 200;
if (cx > XMAXSCREEN - 200) cx = XMAXSCREEN - 200;
if (cy < 300) cy = 300;
if (cy > YMAXSCREEN - 300) cy = YMAXSCREEN - 300;
if (oldshowcase==0) { cx -= 150; cy -= 200; }
sprintf(xctr, "%d", cx);
sprintf(yctr, "%d", cy);
tmpdir = (char *)getenv("TMPDIR");
if (tmpdir == 0) {
tmpfilename = (char *)malloc(20);
strcpy(tmpfilename, "/tmp/showcase_tmp");
} else {
tmpfilename = (char *)malloc(strlen(tmpdir) + 20);
strcpy(tmpfilename, tmpdir);
strcat(tmpfilename,"/showcase_tmp");
}
omask = umask(0);
mkdir (tmpfilename,0777);
mkdir ("/usr/tmp/showcase_tmp",0777);
umask(omask);
free(tmpfilename);
if (!(doexec("browsegizmo", xctr, yctr, title, dir)))
return;
senddevtogizmo(GIZMOINITEND);
browsegizmodead = 0;
while (1) {
dev = halfbakedqread(&val);
switch (dev) {
case DIRNAMEDEV:
readfromgizmo(dir, val);
break;
case FILENAMEDEV:
readfromgizmo(str, val);
senddevtogizmo(ABORT);
senddevtogizmo(0);
return;
case NUKEFILENAMEDEV:
s = (char *)malloc(val);
readfromgizmo(s, val);
free(s);
break;
case ABORT:
senddevtogizmo(ABORT);
senddevtogizmo(0);
qreset();
return;
case DEADGIZMO:
*str = 0; *dir = 0;
qreset();
return;
default:
sendgizmo(POKEGIZMO);
break;
}
}
}
static void catchsignal(int sig)
{
long giz;
switch(sig) {
case SIGCLD:
giz = wait(0);
if (giz == childpid) {
childpid = 0;
browsegizmodead = 1;
}
break;
case SIGILL:
fprintf(stderr, "SIGILL signal\n");
goto savefile;
case SIGQUIT:
fprintf(stderr, "SIGQUIT signal\n");
goto savefile;
case SIGTERM:
fprintf(stderr, "SIGTERM signal\n");
goto savefile;
case SIGIOT:
fprintf(stderr, "SIGIOT signal\n");
break;
case SIGIO:
fprintf(stderr, "SIGIO signal\n");
break;
case SIGPIPE:
fprintf(stderr, "SIGPIPE!\n");
break;
default:
fprintf(stderr, "Unknown signal %d\n", sig);
savefile:
exit(1);
}
signal(sig, catchsignal);
return;
}